﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using cwtrock.model;
using cwtrock.service.impl;
using System.Text.RegularExpressions;
using cwtrock.syscommon;
using cwtrock.util;

namespace cwtrock.view
{
    public partial class VoucherFrm : Form
    {
        private VoucherServiceImpl voucherServiceImpl = new VoucherServiceImpl();
        private static VoucherFrm frm = null;
        private VrecordsServiceImpl vrecordsServiceImpl = new VrecordsServiceImpl();
        private SysDataServiceImpl sysDataServiceImpl = new SysDataServiceImpl();
        private AccountsServiceImpl accountsServiceImpl = new AccountsServiceImpl();
        private List<Vouchers> vouls = new List<Vouchers>();
        private SysUsr currentUser;
        // 4个空格 tab键
        private string space_4 = "  ";
        private List<Accounts> accountls = new List<Accounts>();
        // 选中的凭证类别代码
        private string selVcode;
   
        #region 单体模式
        /// <summary>
        /// 单体模式
        /// </summary>
        /// <returns></returns>
        public static VoucherFrm getInstance()
        {
            if (frm == null)
            {
                frm = new VoucherFrm();
                frm.getToolBtn.Enabled = false;
            }

            return frm;
        }
        #endregion

        private VoucherFrm()
        {
            InitializeComponent();
            dataGridView1.Rows.Add(5);
            dataGridView1.AllowUserToAddRows = true;
     
            initFrm();
           
            for (int i = 1; i < dataGridView1.Rows.Count; i++)
            {

              dataGridView1.Rows[i].ReadOnly = true;
            }
            dataGridView1.Rows[0].Selected = false;
          //  dataGridView1.Rows[0].Cells[0].Selected = false;
        }

        private void initFrm() {

            // 去除表头排序
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
            {
                dataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
            }

            // 初始化凭证字Combo
            List<SysData> sysdatals = sysDataServiceImpl.getSysDataByType(SysConst.SYS_DATA_TYPE);
            if(sysdatals == null)
                return;
            vtype_combo.DataSource = sysdatals;
            vtype_combo.DisplayMember = "itemname";
            vtype_combo.ValueMember = "itemcode";

            currentUser = AppContextProvider.instance.LogUser;
            maker_txt.Text = currentUser.Usrname;

            // 初始化凭证字号 顺序号
            string userid = currentUser.Usrid;
            vouls = voucherServiceImpl.getVouchersByUserId(userid);
            int seqno = getMaxSeqno();
        
           vseq_text.Text = seqno+"";

           SysData sysdata = (SysData)vtype_combo.SelectedItem;
           int vcode = getMaxVodeByVtype(sysdata.Itemcode);
           vtype_nums.Value = vcode;

            // 全部的科目数据
           accountls = accountsServiceImpl.getAcctAll();

           vScrollBar1.Maximum = (dataGridView1.RowCount) * dataGridView1.RowTemplate.Height;
           vScrollBar1.Minimum = 0;
           vScrollBar1.SmallChange = dataGridView1.RowTemplate.Height;
           vScrollBar1.LargeChange = dataGridView1.RowTemplate.Height * 3;
           isDisplay();

        }

        // 获取用户当前的最大顺序号
        private int getMaxSeqno() {
            int seqno = 0;
               

            if (vouls != null && vouls.Count > 0)
            {
                foreach (Vouchers vou in vouls)
                {
                    if (vou.Vseqno > seqno)
                    {

                        seqno = vou.Vseqno;
                    }

                }

            }
            return ++seqno;

        }


        // 取得当前凭证字下的最大编号
        private int getMaxVodeByVtype(string vtype) { 
            int maxvcode=0;
            if (vouls != null && vouls.Count>0)
            { 
             foreach(Vouchers vou in vouls)
             {
                 if (vou.Vtype != null && vou.Vtype.Equals(vtype))
                 {
                    int mcode =vou.Vcode;
                    if (mcode > maxvcode)
                        maxvcode = mcode;
                 }
             
             }
           
          }
         return ++maxvcode;
        
        }


        private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (dataGridView1.CurrentCell == null)
                return;

            int curCol = dataGridView1.CurrentCell.OwningColumn.Index;
            int row = dataGridView1.CurrentCell.OwningRow.Index;
        

            // 改变借方金额单元格的值
            if (curCol == 2)
            {

                
                string loanm = (string)dataGridView1.Rows[row].Cells[3].Value;

                // 当贷方金额有值时，同行的借方金额栏不允许输入
                if (loanm != null)
                {
                    dataGridView1.Rows[row].Cells[2].Value = "";
                    return;


                }
                int borm = 0;
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                   string bor =(string) dataGridView1.Rows[i].Cells[2].Value;
                   try
                   {
                       borm += Convert.ToInt32(bor);
                   }
                   catch (Exception ex) { 
                   
                   }
                }

                dataGridView2[0, 0].Value = borm;
            }


            // 改变贷方金额单元格的值
            if (curCol == 3)
                {


                //    int row = dataGridView1.CurrentCell.OwningRow.Index;
                    string borm = (string)dataGridView1.Rows[row].Cells[2].Value;

                    // 当借方金额有值时，同行的贷方金额栏不允许输入
                    if (borm != null)
                    {
                        dataGridView1.Rows[row].Cells[3].Value = "";
                        return;


                    }



                int loanm = 0;
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    string loan = (string)dataGridView1.Rows[i].Cells[3].Value;
                    try
                    {
                        loanm += Convert.ToInt32(loan);
                    }
                    catch (Exception ex)
                    {

                    }
                }

                dataGridView2.Rows[0].Cells[1].Value = loanm;
            }

        }



        private void VoucherFrm_FormClosing(object sender, FormClosingEventArgs e)
        {
            frm = null;
        }

        private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            if (dataGridView1.CurrentCell == null)
                return;

            int curCol = dataGridView1.CurrentCell.OwningColumn.Index;

            if (curCol == 1)
            {
                getToolBtn.Enabled = true;
            }
            else
            {

                getToolBtn.Enabled = false;
            }
        }

        private void getToolBtn_Click(object sender, EventArgs e)
        {
           
            AccountsMainFrm acctfrm = AccountsMainFrm.getInstance("确定");
            DialogResult rlt = acctfrm.ShowDialog();
            if (rlt == DialogResult.OK)
            {
                if (dataGridView1.CurrentCell == null)
                    return;

                int curCol = dataGridView1.CurrentCell.OwningColumn.Index;

                if (curCol != 1)
                    return;
                int row = dataGridView1.CurrentCell.OwningRow.Index;
                string acctcode = acctfrm.Selacctcode;
                               

                // 判断会计科目是否是明显科目，非明细，报错
                int childcnt =  accountsServiceImpl.getChildCntByAcct(acctcode);
                if (childcnt > 0)
                {
                    MessageBox.Show("科目'" + acctcode + "'不是一个明细科目！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                else {
                    string acctname = accountsServiceImpl.getAcctname(accountls, acctcode);
                    dataGridView1.CurrentCell.Value = null;
                    dataGridView1.EndEdit();
                    dataGridView1.Rows[row].Cells[curCol].Value = acctcode + space_4 + acctname;
                    dataGridView1.EndEdit();
                
                }

            }

        }

        private void save_Click(object sender, EventArgs e)
        {
            try
            {
                // 保存验证
                bool b = validateVoucher();
                // 验证失败
                if (!b)
                    return;

                Vouchers vou = new Vouchers();
                vou.Abid = 1;
                vou.Vcode = (int)vtype_nums.Value ;
                string vtype = "";
                string vtypename = "";
                SysData sysdata = (SysData)vtype_combo.SelectedItem;
                if (sysdata != null)
                {
                    vtype = sysdata.Itemcode;
                    vtypename = sysdata.Itemname;
                }

                vou.Vtype = vtype;
                vou.Vtypename = vtypename;
                vou.Vattaches = Int32.Parse(vattaches_num.Value + "");
                vou.Vcheckerid = "";
                vou.Vchecker = "";
                vou.Vmakerid = currentUser.Usrid;
                vou.Vmaker = currentUser.Usrname;
                vou.Vposter = "";
                vou.Vposterid = "";
                // 凭证状态
                vou.Vcheckstat = SysConst.VOUCHER_CHECKED_NO;
                vou.Vclosedstat = SysConst.VOUCHER_CLOSED_NO;
                vou.Vusedstat = SysConst.VOUCHER_UESED_NO;
                vou.Vpoststat = SysConst.VOUCHER_POST_NO;
                vou.Vdate = vdate_dp.Value;
                vou.Vseqno = Int32.Parse(vseq_text.Text.Trim());
                vou.Vcode = Int32.Parse( vtype_nums.Text.Trim());

                vou = voucherServiceImpl.save(vou);

                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {

                    int col = 0;
                    string digest = (string)dataGridView1.Rows[i].Cells[col++].Value;

                    if (digest == null || "".Equals(digest))
                        break;


                    string acct = (string)dataGridView1.Rows[i].Cells[col++].Value;
                    string acctcode = "";
                    string acctname = "";

                    string[] acctArr = Regex.Split(acct, "  ", RegexOptions.IgnoreCase);
                    if (acctArr != null && acctArr.Length > 0)
                    {
                        acctcode = acctArr[0];
                        acctname = acctArr[1];
                    }


                    string bamount = (string)dataGridView1.Rows[i].Cells[col++].Value;
                    string lamount = (string)dataGridView1.Rows[i].Cells[col++].Value;

                    Vrecords vrecord = new Vrecords();
                    vrecord.Vrdigest = digest;
                    vrecord.Acctcode = acctcode;
                    vrecord.Acctname = acctname;
                    vrecord.Vrbamount = bamount == null ? 0 : decimal.Parse(bamount);
                    vrecord.Vrlamount = lamount == null ? 0 : decimal.Parse(lamount);
                    vrecord.Vid = vou.Id;
                    vrecord.Vcheckerid = "";
                    vrecord.Vchecker = "";
                    vrecord.Vmakerid = currentUser.Usrid;
                    vrecord.Vmaker = currentUser.Usrname;
                    vrecord.Vposter = "";
                    vrecord.Vposterid = "";
                    // 凭证状态
                    vrecord.Vcheckstat = SysConst.VOUCHER_CHECKED_NO;
                    vrecord.Vclosedstat = SysConst.VOUCHER_CLOSED_NO;
                    vrecord.Vusedstat = SysConst.VOUCHER_UESED_NO;
                    vrecord.Vpoststat = SysConst.VOUCHER_POST_NO;
                    vrecordsServiceImpl.save(vrecord);

                    // 刷新列表
                    VoucherListMain lsfrm = VoucherListMain.getInstance();
                    lsfrm.initGrid();
                   
                }
                MessageBox.Show("记账凭证保存成功！ ", "成功 ", MessageBoxButtons.OK, MessageBoxIcon.Information);

            }
                catch (Exception ex) {
                    MessageBox.Show("记账凭证保存失败！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    throw ex;
                   
                }

        }

        private bool validateVoucher() {

            int borrowTotal = 0;
            int loanTotal = 0;

            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                int col = 0;
                string digest = (string)dataGridView1.Rows[i].Cells[col++].Value;
                string acct = (string)dataGridView1.Rows[i].Cells[col++].Value;
                string bamount = (string)dataGridView1.Rows[i].Cells[col++].Value;
                string lamount = (string)dataGridView1.Rows[i].Cells[col++].Value;

                vouls = voucherServiceImpl.getVouchersByUserId(currentUser.Usrid);


              // 验证首行分录
                if (i == 0)
                {
                    bool b = validForm(i,borrowTotal, loanTotal);
                  if (!b)
                  return false;
                    
                }
                // 验证非首行分录
                if (i > 0)
                {
                    if (!(SimpleTool.isEmpty(digest)
                          && SimpleTool.isEmpty(acct) && SimpleTool.isEmpty(bamount) && SimpleTool.isEmpty(lamount)))
                    {
                        bool b = validForm(i,borrowTotal, loanTotal);
                        if (!b)
                        return false;
                   }
                
                }

                // 累计收支
                if (!SimpleTool.isEmpty(bamount))
                {
                    borrowTotal += Int32.Parse(bamount);

                }

                if (!SimpleTool.isEmpty(lamount))
                {
                    loanTotal += Int32.Parse(lamount);

                }
          
            }

            if (borrowTotal != loanTotal)
            {
                MessageBox.Show("记账凭证借贷不平衡！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;

            }

          
            string seqno = vseq_text.Text.Trim();
            string vcode = vtype_nums.Text.Trim();

            int seqnoCnt =voucherServiceImpl.getVouchersCntByUserAndSeqno(seqno,currentUser.Usrid);
            int vcodeCnt = voucherServiceImpl.getVouchersCntByUserAndVcode(vcode,selVcode, currentUser.Usrid);

            //顺序号,凭证号都重复
            if (seqnoCnt > 0 && vcodeCnt>0)
            {

                DialogResult dialogResult = MessageBox.Show("顺序号与凭证号重复，凭证保存不成功，系统将重新编号，是否继续？", "警告", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {

                    int seqnonum = getMaxSeqno();
                    vseq_text.Text = seqnonum + "";
                    SysData sysdata = (SysData)vtype_combo.SelectedItem;
                    int vcodenum = getMaxVodeByVtype(sysdata.Itemcode);
                    vtype_nums.Value = vcodenum;

                }
               
               return false;
               
            
            }

            // 顺序号重复
            else  if (seqnoCnt > 0)
            {


                DialogResult dialogResult = MessageBox.Show("顺序号'" + seqno + "'重复，凭证保存不成功，系统将重新编号，是否继续？", "警告", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes) {

                    int seqnonum = getMaxSeqno();
                    vseq_text.Text = seqnonum + "";
                
                }
               
                return false;
            }

          // 凭证号重复
          else  if (vcodeCnt > 0)
            {

             DialogResult dialogResult = MessageBox.Show("凭证号'" + vcode + "'重复，凭证保存不成功，系统将重新编号，是否继续？", "警告", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    SysData sysdata = (SysData)vtype_combo.SelectedItem;
                    int vcodenum = getMaxVodeByVtype(sysdata.Itemcode);
                    vtype_nums.Value = vcodenum;
                    
                }
          
                return false;
               
            }

            return true;
        }

        private bool validForm(int i,int borrowTotal,int loanTotal)
        {

            int col = 0;
            string digest = (string)dataGridView1.Rows[i].Cells[col++].Value;
            if (SimpleTool.isEmpty(digest))
            {
                MessageBox.Show("摘要不允许为空值！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }

            string acct = (string)dataGridView1.Rows[i].Cells[col++].Value;
            if (SimpleTool.isEmpty(acct))
            {
                MessageBox.Show("会计科目不允许为空值！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }
            string bamount = (string)dataGridView1.Rows[i].Cells[col++].Value;
            string lamount = (string)dataGridView1.Rows[i].Cells[col++].Value;

            if (SimpleTool.isEmpty(bamount) && SimpleTool.isEmpty(lamount))
            {
                MessageBox.Show("缺少会计分录！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }

            if ("0".Equals(bamount) || "0".Equals(lamount))
            {
                MessageBox.Show("会计分录不能为零！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return false;
            }
          

            return true;
        }


        // 屏蔽非数字键
        private void vsecq_text_KeyPress(object sender, KeyPressEventArgs e)
        {
            base.OnKeyPress(e);

          
            if ((int)e.KeyChar <= 32)  // 特殊键(含空格), 不处理
            {
                return;
            }

            if (!char.IsDigit(e.KeyChar))  // 非数字键, 放弃该输入
            {
                e.Handled = true;
                return;
            }
        }


 
        private void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            int row = e.RowIndex;
            int curCol = dataGridView1.CurrentCell.OwningColumn.Index;
            if (curCol == 1)
            {
              
                string acct = e.FormattedValue.ToString();
                string acctcode = "";
                if (acct == null)
                    return;

                string[] selacctArr = Regex.Split(acct, space_4, RegexOptions.IgnoreCase);

                if (selacctArr.Length > 0)
                    acctcode = selacctArr[0].Trim();
                if (SimpleTool.isEmpty(acctcode))
                {
                    return;
                }

                string acctname = accountsServiceImpl.getAcctname(accountls,acctcode);

                // 判断科目存在性
                if (SimpleTool.isEmpty(acctname))
                {
                   
                    e.Cancel = true;
                  //  dataGridView1.Rows[e.RowIndex].ErrorText = "the value must be a non-negative integer";
                    MessageBox.Show("科目'" + acctcode + "'不存在！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;

                }

                // 判断会计科目是否是明显科目，非明细，报错
                int childcnt = accountsServiceImpl.getChildCntByAcct(acctcode);
                if (childcnt > 0)
                {
                    e.Cancel = true;
                    MessageBox.Show("科目'" + acctcode + "'不是一个明细科目！ ", "警告 ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                   
                    return;
                }

                // 合法科目代码
                dataGridView1.Rows[row].Cells[curCol].Value = null;
                dataGridView1.EndEdit();
                dataGridView1.Rows[row].Cells[curCol].Value = acctcode + space_4 + acctname;
                dataGridView1.EndEdit();
              
            }
        }

   


        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            dataGridView1.FirstDisplayedScrollingRowIndex = e.NewValue / dataGridView1.RowTemplate.Height;
            Application.DoEvents();
        }

        private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
        {
            vScrollBar1.Maximum = (dataGridView1.RowCount) * dataGridView1.RowTemplate.Height;
            isDisplay();
        }

        private void dataGridView1_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
        {
            vScrollBar1.Maximum = (dataGridView1.RowCount) * dataGridView1.RowTemplate.Height;
            isDisplay();
        }

        private void isDisplay()
        {
            bool isDisplay = (dataGridView1.RowCount+1) * dataGridView1.RowTemplate.Height <= dataGridView1.Height;
            vScrollBar1.Enabled = !isDisplay;
        }

        private void vtype_combo_SelectedValueChanged(object sender, EventArgs e)
        {
            SysData sysdata = (SysData)vtype_combo.SelectedItem;
            selVcode = sysdata.Itemcode;
            int vcode = getMaxVodeByVtype(sysdata.Itemcode);
            vtype_nums.Value = vcode;
        }


         // 对下一行解锁
        private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int curRow = e.RowIndex;
            int nextRow = curRow + 1;
            if (nextRow < dataGridView1.RowCount
                   && !(dataGridView1.Rows[curRow].ReadOnly))
            {
                int col = 0;
                string digest = (string)dataGridView1.Rows[curRow].Cells[col++].Value;
                string acct = (string)dataGridView1.Rows[curRow].Cells[col++].Value;
                string bamount = (string)dataGridView1.Rows[curRow].Cells[col++].Value;
                string lamount = (string)dataGridView1.Rows[curRow].Cells[col++].Value;
                if (SimpleTool.isNotEmpty(digest) && SimpleTool.isNotEmpty(acct)
                    && (SimpleTool.isNotEmpty(bamount) || SimpleTool.isNotEmpty(lamount)))
                {
                    dataGridView1.Rows[nextRow].ReadOnly = false;
                }
            }
        }

        private void VoucherFrm_Load(object sender, EventArgs e)
        {
            dataGridView1.Rows[0].Selected = false;
            dataGridView2.Rows[0].Selected = false;
            dataGridView1.Rows[0].Cells[0].Selected = false;
        }

    }
}
